package edu.suda.xsap.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import edu.suda.xsap.dto.MemberBindRecordDto;
import edu.suda.xsap.dto.MemberCardDto;
import edu.suda.xsap.dto.MemberDto;
import edu.suda.xsap.dto.MemberWithCardsDto;
import edu.suda.xsap.dto.convert.MemberCardConvert;
import edu.suda.xsap.dto.convert.MemberConvert;
import edu.suda.xsap.entity.ID;
import edu.suda.xsap.entity.Member;
import edu.suda.xsap.entity.MemberBind;
import edu.suda.xsap.entity.MemberCard;
import edu.suda.xsap.mapper.MemberMapper;
import edu.suda.xsap.mapper.MemberCardMapper;
import edu.suda.xsap.service.MemberService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;


import java.sql.Date;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;
import java.util.Map;

@Service
public class MemberServiceImpl implements MemberService {

    @Autowired
    private MemberConvert memberConvert;

    @Autowired
    private MemberMapper memberMapper;

    @Autowired
    private MemberCardConvert memberCardConvert;

    @Autowired
    private MemberCardMapper MemberCardMapper;
    @Autowired
    private MemberCardMapper memberCardMapper;


    public Long addMember(MemberDto memberDto) {
        // 将DTO转换为实体类
        Member member = memberConvert.toEntity(memberDto);

        // 保存会员信息到数据库
        memberMapper.save(member);

        // 返回生成的会员ID
        return member.getId();
    }

    @Override
    public Long bindCard(Long memberId, MemberCardDto memberCardDto) {
//        System.out.println("im here2");
        // 将DTO转换为实体类
        MemberCard memberCard = memberCardConvert.toCardEntity(memberCardDto);
//        System.out.println("im here3");
        // 将会员卡数据插入表中,id自动更新
        memberCardMapper.save(memberCard);

        //打印会员卡id
//        System.out.println("会员卡id: " + memberCard.getId());

        // 将会员id和会员卡id绑定，插入到bind表中
        MemberBindRecordDto memberBindRecordDto = new MemberBindRecordDto();
        memberBindRecordDto.setCardId(memberCard.getId());
        memberBindRecordDto.setMemberId(memberId);

        //打印bind对应的数据
        System.out.println("bind表对应的数据: " + memberBindRecordDto);

        memberMapper.bindCard(memberBindRecordDto);

        // 返回生成的会员卡ID
        return memberBindRecordDto.getId();
    }

    @Override
    public void delete(Long memberId) {
        //先将会员对应的绑定记录删掉（卡不删掉，因为也许卡可以换绑）
        //todo:删除时最先删除的是recharge_record表，因为这里还没涉及到充值记录，所以先不删除
        //这导致只有后续手动添加的不涉及充值的记录，才能删除，前面的记录无法删除
        memberMapper.deleteBind(memberId);
        memberMapper.delete(memberId);
    }

    //添加分页
//    @Override
//    public MemberWithCardsDto findAll(int page, int size) {
//
//        // 启动分页查询
//        PageHelper.startPage(page, size);
//        // 执行查询
//        List<Member> members = memberMapper.findAll();
//        // 返回分页信息
//        return memberConvert.toDtoList(members);
//    }

    @Override
    public PageInfo<MemberWithCardsDto> findAll(int page, int size) {
        // 启动分页查询
        PageHelper.startPage(page, size);

        // 执行查询
        List<Member> members = memberMapper.findAll();
//        System.out.println("查询到的会员数据: " + members);

        // 获取所有会员的 ID
        List<Long> memberIds = members.stream()
                .map(Member::getId)
                .collect(Collectors.toList());
//        System.out.println("会员 ID 列表: " + memberIds);

        // 查询所有会员卡信息
        List<MemberCard> memberCards = MemberCardMapper.findMemberCardsByMemberIds(memberIds);
//        System.out.println("查询到的会员卡数据: " + memberCards);

        // 查询所有会员卡绑定信息
        List<MemberBind> memberBinds = memberCardMapper.findMemberBindsByMemberIds(memberIds);
//        System.out.println("查询到的会员卡绑定数据: " + memberBinds);

//        // 创建会员卡映射
//        // 将会员卡按照会员 ID 分组，value 是会员卡列表
//        Map<Long, List<MemberCardDto>> memberCardMap = memberCards.stream()
//                .collect(Collectors.groupingBy(
//                        // 这里的 `getMemberId` 需要根据实际的成员 ID 字段名称来设置
//                        MemberCard::getMemberId,
//                        Collectors.mapping(memberConvert::toCardDto, Collectors.toList())
//                ));
//        System.out.println("会员卡映射: " + memberCardMap);

// 根据会员ID将会员卡进行分组，并转换为 MemberCardDto
        Map<Long, List<MemberCardDto>> memberCardMap = memberBinds.stream()
                .collect(Collectors.groupingBy(
                        MemberBind::getMemberId,
                        Collectors.mapping(
                                bind -> memberCards.stream()
                                        .filter(card -> card.getId().equals(bind.getCardId()))
                                        .map(memberConvert::toCardDto) // 将 MemberCard 转换为 MemberCardDto
                                        .findFirst().orElse(null),
                                Collectors.toList()
                        )
                ));

// 输出会员卡映射结果
//        System.out.println("会员卡映射: " + memberCardMap);


        // 将 Member 列表转换为 MemberWithCardsDto 列表
        List<MemberWithCardsDto> memberWithCardsDtos = members.stream().map(member -> {
            // 转换 Member 为 MemberDto
            MemberDto memberDto = memberConvert.toDto(member);

            // 获取当前会员的会员卡信息
            List<MemberCardDto> memberCardDtos = memberCardMap.getOrDefault(member.getId(), Collections.emptyList());

            // 创建 MemberWithCardsDto 对象
            MemberWithCardsDto memberWithCardsDto = new MemberWithCardsDto();
            memberWithCardsDto.setId(memberDto.getId());
            memberWithCardsDto.setName(memberDto.getName());
            memberWithCardsDto.setSex(memberDto.getSex());
            memberWithCardsDto.setPhoneNumber(memberDto.getPhone());
            //先判断生日是否为空，如果为空则设置为null，否则设置为Date类型
            if (memberDto.getBirthday() == null) {
                memberWithCardsDto.setBirthDay(null);
            } else {
                memberWithCardsDto.setBirthDay(Date.valueOf(memberDto.getBirthday()));
            }
            memberWithCardsDto.setNote(memberDto.getNote());
            memberWithCardsDto.setMemberCards(memberCardDtos);

            return memberWithCardsDto;
        }).collect(Collectors.toList());

        // 使用 PageInfo 包装结果并返回
        return new PageInfo<>(memberWithCardsDtos);
    }

    @Override
    public Member findById(Long id) {
        return memberMapper.findById(id);
    }
}
